"""
主控制模块
整合各个功能模块，实现上位机核心控制逻辑
"""

import time
import threading
from typing import Dict, Any, Callable
from data_control import get_audio_data_manager
from system_state import get_state_manager, SystemState
from motion_generator import get_motion_generator, DanceMode
from robot_comm import get_robot_communicator
from exception_handler import get_exception_handler, ExceptionType
from config_manager import get_config_manager


class MainController:
    """
    主控制器
    负责协调各个模块，实现上位机核心控制逻辑
    """
    
    def __init__(self):
        """初始化主控制器"""
        # 获取各个模块的实例
        self.audio_manager = get_audio_data_manager()
        self.state_manager = get_state_manager()
        self.motion_generator = get_motion_generator()
        self.robot_comm = get_robot_communicator()
        self.exception_handler = get_exception_handler()
        self.config_manager = get_config_manager()
        
        # 音频处理相关
        self.audio_processor = None
        
        # 控制标志
        self.running = False
        self.control_thread = None
        
        # 注册状态变化监听器
        self.state_manager.add_state_listener(self._on_state_change)
        
        # 注册异常监听器
        self.exception_handler.add_exception_listener(self._on_exception)
        
    def initialize_system(self) -> bool:
        """
        初始化系统
        
        Returns:
            bool: 初始化是否成功
        """
        try:
            print("正在初始化系统...")
            
            # 1. 加载配置
            self._load_system_config()
            
            # 2. 初始化音频设备
            self._initialize_audio()
            
            # 3. 连接机器人
            self._connect_robot()
            
            # 4. 初始化舞蹈序列
            self._initialize_dance_sequences()
            
            # 5. 设置系统为就绪状态
            self.state_manager.set_state(SystemState.READY)
            
            print("系统初始化完成")
            return True
            
        except Exception as e:
            self.exception_handler.handle_exception(
                ExceptionType.SYSTEM_RESOURCE_ERROR,
                f"系统初始化失败: {str(e)}",
                self._on_initialization_error
            )
            return False
            
    def _load_system_config(self):
        """加载系统配置"""
        print("加载系统配置...")
        # 配置已经在ConfigManager初始化时加载
        # 这里可以执行一些额外的配置处理
        
        # 加载WiFi配置到UI
        wifi_config = self.config_manager.get_section('wifi_config')
        if wifi_config:
            # 这里可以添加将配置加载到UI的逻辑
            pass
        
    def _initialize_audio(self):
        """初始化音频设备"""
        print("初始化音频设备...")
        # 音频设备初始化逻辑
        # 实际实现中需要初始化音频输入设备
        try:
            from music import RealTimeAudioProcessor, analysis_callback
            from data_control import data_callback
            
            # 创建实时音频处理器
            self.audio_processor = RealTimeAudioProcessor()
            
            # 设置分析回调函数，将数据传递给data_control模块
            def audio_analysis_callback(audio_data, features):
                # 调用原始的分析回调打印信息
                analysis_callback(audio_data, features)
                # 将数据传递给data_control模块进行封装
                data_callback(audio_data, features)
                
            self.audio_processor.set_analysis_callback(audio_analysis_callback)
            
            print("音频处理初始化完成")
        except ImportError as e:
            error_msg = f"音频模块导入失败: {str(e)}"
            print(error_msg)
            self.exception_handler.handle_exception(
                ExceptionType.SYSTEM_RESOURCE_ERROR,
                error_msg,
                None
            )
            raise
        except Exception as e:
            error_msg = f"音频设备初始化失败: {str(e)}"
            print(error_msg)
            self.exception_handler.handle_exception(
                ExceptionType.SYSTEM_RESOURCE_ERROR,
                error_msg,
                None
            )
            raise
            
    def _connect_robot(self):
        """连接机器人"""
        print("连接机器人...")
        robot_address = self.config_manager.get('robot.address', '192.168.1.100')
        robot_port = self.config_manager.get('robot.port', 8080)
        connection_type = self.config_manager.get('robot.connection_type', 'tcp')
        
        address = f"{robot_address}:{robot_port}" if connection_type == 'tcp' else robot_address
        success = self.robot_comm.connect(address)
        
        if not success:
            self.exception_handler.handle_exception(
                ExceptionType.NETWORK_ERROR,
                f"无法连接到机器人: {address}",
                None,
                auto_retry=True
            )
            
    def _initialize_dance_sequences(self):
        """初始化舞蹈序列"""
        print("初始化舞蹈序列...")
        # 加载预设舞蹈序列
        # 实际实现中需要从文件或数据库加载
        
    def _on_initialization_error(self, result: str):
        """
        初始化错误回调
        
        Args:
            result: 错误处理结果
        """
        print(f"初始化错误处理结果: {result}")
        
    def start_realtime_mode(self):
        """启动实时模式"""
        if not self._can_transit_to(SystemState.PLAYING):
            print(f"无法切换到播放状态，当前状态: {self.state_manager.get_current_state()}")
            return False
            
        print("启动实时模式...")
        self.motion_generator.mode = DanceMode.REALTIME
        
        # 确保音频处理器已启动
        if hasattr(self, 'audio_processor'):
            print("尝试启动音频录制...")
            success = self.audio_processor.start_recording("realtime_dance.wav")
            if success:
                print("音频录制已启动")
            else:
                print("警告: 音频录制启动失败")
                return False
        else:
            print("错误: 音频处理器未初始化")
            return False
            
        self.state_manager.set_state(SystemState.PLAYING)
        
        # 启动控制线程
        self._start_control_loop()
        print("实时模式启动完成")
        return True
        
    def start_preset_mode(self, sequence_id: str = None):
        """启动预设模式"""
        if not self._can_transit_to(SystemState.PLAYING):
            return False
            
        print("启动预设模式...")
        self.motion_generator.mode = DanceMode.PRESET
        
        # 加载预设序列
        if sequence_id:
            self.motion_generator.current_sequence = \
                self.motion_generator.load_preset_sequence(sequence_id)
        else:
            # 加载默认序列
            self.motion_generator.current_sequence = \
                self.motion_generator.load_preset_sequence("default")
                
        self.motion_generator.current_action_index = 0
        self.state_manager.set_state(SystemState.PLAYING)
        
        # 启动控制线程
        self._start_control_loop()
        return True
        
    def start_recording_mode(self):
        """启动录制模式"""
        if not self._can_transit_to(SystemState.PLAYING):
            return False
            
        print("启动录制模式...")
        self.motion_generator.mode = DanceMode.RECORDING
        
        # 初始化录制相关设置
        self.motion_generator.current_sequence = None
        self.motion_generator.current_action_index = 0
        self.state_manager.set_state(SystemState.PLAYING)
        
        # 启动控制线程
        self._start_control_loop()
        return True
        
    def start_editing_mode(self):
        """启动编辑模式"""
        if not self._can_transit_to(SystemState.PLAYING):
            return False
            
        print("启动编辑模式...")
        self.motion_generator.mode = DanceMode.EDITING
        
        # 对于编辑模式，不重置当前序列，因为它已经在UI中设置过了
        # 只重置索引
        self.motion_generator.current_action_index = 0
        self.state_manager.set_state(SystemState.PLAYING)
        
        # 启动控制线程
        self._start_control_loop()
        return True

    def pause(self):
        """暂停系统"""
        if not self._can_transit_to(SystemState.PAUSED):
            return False
            
        print("暂停系统...")
        self.state_manager.set_state(SystemState.PAUSED)
        return True
        
    def resume(self):
        """恢复系统"""
        if self.state_manager.get_current_state() != SystemState.PAUSED:
            return False
            
        print("恢复系统...")
        self.state_manager.set_state(SystemState.PLAYING)
        return True
        
    def stop(self):
        """停止系统"""
        current_state = self.state_manager.get_current_state()
        if current_state in [SystemState.IDLE, SystemState.READY]:
            return False
            
        print("停止系统...")
        self.running = False
        
        # 停止音频录制（如果是实时模式）
        if (hasattr(self, 'audio_processor') and 
            self.motion_generator.mode == DanceMode.REALTIME):
            print("停止音频录制...")
            self.audio_processor.stop_recording()
        
        # 等待控制线程结束
        if self.control_thread and self.control_thread.is_alive():
            self.control_thread.join(timeout=2)
            
        self.state_manager.set_state(SystemState.READY)
        return True
        
    def _can_transit_to(self, target_state: SystemState) -> bool:
        """
        检查是否可以转换到目标状态
        
        Args:
            target_state: 目标状态
            
        Returns:
            bool: 是否可以转换
        """
        return self.state_manager.can_transit_to(target_state)
        
    def _start_control_loop(self):
        """启动控制循环"""
        self.running = True
        self.control_thread = threading.Thread(target=self._control_loop)
        self.control_thread.daemon = True
        self.control_thread.start()
        
    def _control_loop(self):
        """控制主循环"""
        print("控制循环启动...")
        
        while self.running:
            try:
                current_state = self.state_manager.get_current_state()
                
                # 根据当前状态执行不同逻辑
                if current_state == SystemState.PLAYING:
                    self._process_playing_state()
                elif current_state == SystemState.PAUSED:
                    # 暂停状态下休眠
                    time.sleep(0.1)
                    continue
                    
                # 控制循环频率
                time.sleep(0.01)  # 10ms循环间隔
                
            except Exception as e:
                self.exception_handler.handle_exception(
                    ExceptionType.SYSTEM_RESOURCE_ERROR,
                    f"控制循环异常: {str(e)}",
                    None
                )
                break
                
        print("控制循环结束")
        
    def _process_playing_state(self):
        """处理播放状态"""
        # 根据舞蹈模式执行不同逻辑
        if self.motion_generator.mode == DanceMode.REALTIME:
            self._process_realtime_mode()
        elif self.motion_generator.mode == DanceMode.PRESET:
            self._process_preset_mode()
        elif self.motion_generator.mode == DanceMode.RECORDING:
            self._process_recording_mode()
        elif self.motion_generator.mode == DanceMode.EDITING:
            self._process_editing_mode()
            
    def _process_realtime_mode(self):
        """处理实时模式"""
        # 获取当前音频数据
        audio_data = self.audio_manager.get_current_data()
        
        if audio_data and audio_data['features']:
            try:
                # 生成实时动作
                action = self.motion_generator.generate_realtime_action(audio_data['features'])
                
                # 只在检测到节拍时打印详细的音频特征信息
                features = audio_data['features']
                if features.get('is_beat', False):
                    print(f"音频特征 - 音量: {features.get('amplitude_rms', 0):.2f}, "
                          f"频率: {features.get('dominant_frequency', 0):.0f}Hz, "
                          f"节拍: {features.get('is_beat', False)}, "
                          f"BPM: {features.get('bpm', 0):.1f}")
                
                # 执行动作
                if action:
                    # 只在有动作执行且检测到节拍时打印信息
                    if features.get('is_beat', False):
                        print(f"实时模式执行动作: {action.action_id}, 关节角度: {action.joint_angles}, 持续时间: {action.duration}")
                    self.robot_comm.execute_action(action)
                elif features.get('is_beat', False):
                    print("实时模式: 未生成有效动作")
            except Exception as e:
                print(f"实时模式生成或执行动作失败: {str(e)}")
                self.exception_handler.handle_exception(
                    ExceptionType.MOTION_GENERATION_ERROR,
                    f"实时模式生成或执行动作失败: {str(e)}",
                    None
                )
        else:
            # 只偶尔提示没有音频数据（约每秒1次）
            import random
            if random.random() < 0.01:
                print("未获取到音频特征数据")
            
    def _process_preset_mode(self):
        """处理预设模式"""
        # 获取下一个预设动作
        action = self.motion_generator.get_next_preset_action()
        
        if action:
            try:
                # 执行动作
                self.robot_comm.execute_action(action)
            except Exception as e:
                self.exception_handler.handle_exception(
                    ExceptionType.ROBOT_EXECUTION_ERROR,
                    f"预设模式执行动作失败: {str(e)}",
                    None
                )
        else:
            # 序列结束，停止播放
            self.stop()
            
    def _process_recording_mode(self):
        """处理录制模式"""
        # 在录制模式下，可以记录用户的动作输入或音频特征
        # 这里简单处理，实际实现可能需要更多逻辑
        audio_data = self.audio_manager.get_current_data()
        
        if audio_data and audio_data['features']:
            try:
                # 生成实时动作并记录
                action = self.motion_generator.generate_realtime_action(audio_data['features'])
                
                # TODO: 将生成的动作添加到录制序列中 (需要 motion_generator 支持)
                # self.motion_generator.record_action(action)
                
                # 执行动作
                if action:
                    self.robot_comm.execute_action(action)
            except Exception as e:
                self.exception_handler.handle_exception(
                    ExceptionType.MOTION_GENERATION_ERROR,
                    f"录制模式生成或执行动作失败: {str(e)}",
                    None
                )
            
    def _process_editing_mode(self):
        """处理编辑模式"""
        # 在编辑模式下，执行时间轴编辑器中的动作序列
        try:
            # 获取下一个编辑动作
            action = self.motion_generator.get_next_editing_action()
            
            if action:
                print(f"编辑模式执行动作: {action.action_id}, 关节角度: {action.joint_angles}, 持续时间: {action.duration}")
                # 执行动作
                self.robot_comm.execute_action(action)
                # 添加小延迟以控制动作播放速度
                time.sleep(action.duration)
            else:
                # 如果没有动作，短暂休眠
                print("编辑模式: 暂无动作")
                time.sleep(0.1)
        except Exception as e:
            self.exception_handler.handle_exception(
                ExceptionType.ROBOT_EXECUTION_ERROR,
                f"编辑模式执行动作失败: {str(e)}",
                None
            )

    def _on_state_change(self, old_state: SystemState, new_state: SystemState):
        """
        状态变化回调
        
        Args:
            old_state: 旧状态
            new_state: 新状态
        """
        print(f"系统状态变化: {old_state.value} -> {new_state.value}")
        
        # 根据状态变化执行特定逻辑
        if new_state == SystemState.ERROR:
            # 进入错误状态时的安全处理
            self._handle_error_state()
            
    def _on_exception(self, exception_type: ExceptionType, message: str):
        """
        异常回调
        
        Args:
            exception_type: 异常类型
            message: 异常信息
        """
        print(f"捕获异常 [{exception_type.value}]: {message}")
        
        # 根据异常类型更新系统状态
        if exception_type in [ExceptionType.NETWORK_ERROR, 
                             ExceptionType.ROBOT_EXECUTION_ERROR]:
            self.state_manager.set_state(SystemState.ERROR)
            
    def _handle_error_state(self):
        """处理错误状态"""
        print("系统进入错误状态，执行安全措施...")
        
        # 停止控制循环
        self.running = False
        
        # 停止机器人动作
        # 这里应该发送停止命令给机器人
        
        # 尝试恢复连接
        # 可以启动一个恢复线程尝试重新连接
        
    def send_wifi_config(self, wifi_config: Dict[str, Any], serial_port: str) -> bool:
        """
        发送WiFi配置到ESP32
        
        Args:
            wifi_config: WiFi配置字典
            serial_port: 串口名称
            
        Returns:
            bool: 是否发送成功
        """
        try:
            # 保存WiFi配置到本地配置文件
            self.config_manager.update_section('wifi_config', wifi_config)
            self.config_manager.save_config()
            
            # 连接到ESP32串口
            if not self.robot_comm.connect(serial_port):
                return False
                
            # 发送WiFi配置
            self.robot_comm.send_wifi_config(wifi_config)
            
            # 断开连接
            self.robot_comm.disconnect()
            
            return True
            
        except Exception as e:
            print(f"发送WiFi配置失败: {e}")
            return False
            
    def get_system_status(self) -> Dict[str, Any]:
        """
        获取系统状态信息
        
        Returns:
            Dict[str, Any]: 系统状态信息
        """
        return {
            'state': self.state_manager.get_current_state().value,
            'mode': self.motion_generator.mode.value if self.motion_generator.mode else None,
            'robot_status': self.robot_comm.get_status(),
            'audio_stats': self.audio_manager.get_statistics()
        }


# 全局主控制器实例
main_controller = MainController()


def get_main_controller() -> MainController:
    """
    获取全局主控制器实例
    
    Returns:
        MainController: 主控制器实例
    """
    return main_controller